package org.icress.fusion.b2b

import org.icress.fusion.admin.RecordType
import org.icress.fusion.admin.PageLayout
import org.icress.fusion.admin.Profile
import org.icress.fusion.shiro.User
import org.apache.shiro.SecurityUtils
import org.hibernate.FetchMode as FM


import org.icress.fusion.wf.WorkflowHistory
import org.icress.fusion.wf.WorkflowStep

import org.icress.fusion.admin.ShareRoleService
import org.springframework.transaction.annotation.*

class SalesOrderService {

    static transactional = true 
    
	def shareRoleService
	
    @Transactional(readOnly = true)
    def list(Object params) {
		  //get current user
      def currentUser = User.findByUsername( SecurityUtils.getSubject().getPrincipal() )
      def shareUsers = shareRoleService.getShareUserList("salesOrder", "list")
      def salesOrderInstanceList = SalesOrder.withCriteria{
			  if(params?.max) maxResults(params.int('max'))
			  if(params?.offset) firstResult(params.int('offset'))
			  if(params?.sort && params?.order) order(params?.sort, params?.order)
			  if(params?.status) eq("status", params?.status)
        if(currentUser.username != 'admin') {
    	    or{
    		    and{
              inList("owner.id", shareUsers)
              inList("status", ["待审批（办事处）", "待审批（商务部）"])
            }
    			  eq("owner", currentUser)
    		  }
        }
		  }
      return salesOrderInstanceList
    }

    @Transactional(readOnly = true)
    def show(id) {
        //get current user
        def currentUser = User.findByUsername( SecurityUtils.getSubject().getPrincipal() )
        def shareUsers = shareRoleService.getShareUserList("salesOrder", "show")
        def salesOrderInstance = SalesOrder.withCriteria(uniqueResult:true){
            eq("id", id.toLong())
            if(currentUser.username != 'admin') {
                or{
                  and{
                    inList("owner.id", shareUsers)
                    inList("status", ["待审批（办事处）", "待审批（商务部）"])
                  }
                  eq("owner", currentUser)
                }
            }
        }
        return salesOrderInstance
    }
    def edit(id) {
        //get current user
        def currentUser = User.findByUsername( SecurityUtils.getSubject().getPrincipal() )
        def shareUsers = shareRoleService.getShareUserList("salesOrder", "edit")
        def salesOrderInstance = SalesOrder.withCriteria(uniqueResult:true){
            eq("id", id.toLong())
            if(currentUser.username != 'admin') {
                or{
                  and{
                    inList("owner.id", shareUsers)
                    inList("status", ["待审批（办事处）", "待审批（商务部）"])
                  }
                  eq("owner", currentUser)
                }
            }
        }
        return salesOrderInstance
    }
    def delete(id) {
        //get current user
        def currentUser = User.findByUsername( SecurityUtils.getSubject().getPrincipal() )
        def shareUsers = shareRoleService.getShareUserList("salesOrder", "delete")
        def salesOrderInstance = SalesOrder.withCriteria(uniqueResult:true){
            eq("id", id.toLong())
            if(currentUser.username != 'admin') {
                or{
                  and{
                    inList("owner.id", shareUsers)
                    inList("status", ["待审批（办事处）", "待审批（商务部）"])
                  }
                  eq("owner", currentUser)
                }
            }
        }
        return salesOrderInstance
    }
	

    def recordTypeList() {
        def recordTypeList = RecordType.findAllByDomain('salesOrder')
        return recordTypeList
    }
    
    def pageLayoutName(recordTypeId) {
        def currentUser = User.findByUsername( SecurityUtils.getSubject().getPrincipal() )
        def pageLayout = PageLayout.withCriteria{
            eq "domain", "salesOrder"
            eq "recordType.id", recordTypeId
            eq "profile.id", currentUser.profile.id
        }
        return pageLayout[0]?.name
    }
    
    def initSalesOrder(salesOrderInstance) {
        def currentUser = User.findByUsername( SecurityUtils.getSubject().getPrincipal() )
        
        //get dealer, department, salesman
        def dealer = Dealer.withCriteria(uniqueResult:true){
            createAlias 'department', 'dept'
            createAlias 'salesMan', 'staff'
            projections {
                property('id')
                property('dept.id')
                property('staff.id')
                property('address1')
                property('address2')
            }
            join "department"
            join "salesMan"
            eq('owner', currentUser)
            maxResults(1)
            order("serialNumber", "asc")
        }
        if(dealer) {
            salesOrderInstance.dealer = Dealer.get(dealer[0])
            salesOrderInstance.salesMan = Staff.get(dealer[2])
            salesOrderInstance.address1 = dealer[3]
            salesOrderInstance.address2 = dealer[4]
        }
        return salesOrderInstance
    }
    
    def formatSerialNumber(salesOrderInstance) {
        def i = 0
        salesOrderInstance.salesOrderDetails.each { detail ->
            i++
            def detailSerialNumber = (i < 10)?'0' + i: '' + i
            detail.serialNumber = detailSerialNumber
            
            def j = 0
            detail.salesOrderDetailDetails.each { detailDetail ->
                j++
                
                def detailDetailSerialNumber = (j < 10)?'0' + j: '' + j
                detailDetail.serialNumber = detailDetailSerialNumber
            }
        }
        return salesOrderInstance
    }
    
    def save(salesOrderInstance) {
        def success = false
        //SalesOrder.withTransaction{status ->
            //get user
            def currentUser = User.findByUsername( SecurityUtils.getSubject().getPrincipal() )
            //get recprdtypeid
            def recordType = RecordType.get(salesOrderInstance.recordType.id)
            //set instance params
            salesOrderInstance.createdBy = currentUser
            salesOrderInstance.lastModifiedBy = currentUser
            salesOrderInstance.owner = currentUser
            salesOrderInstance.status = "草稿"
            salesOrderInstance.salesOrderDetails.each { 
                it.deliveryLimitation = it.deliveryLimitation?:new Date()
                it.specialDiscount = it.specialDiscount ?: 0
            }
            //save
            success = salesOrderInstance.validate() && salesOrderInstance.save(flush: true)
            //if(!success){
            //    status.setRollbackOnly()
            //}
        //}
        return success
    }
    
    def update(SalesOrder salesOrderInstance, Object params) {
        def success = false
        SalesOrder.withTransaction{ status ->

            //delete details
            SalesOrderDetail.findAllBySalesOrder(salesOrderInstance).each { it.delete(flush:true)}
            salesOrderInstance.save(flush: true)  

            salesOrderInstance.properties = params

            //get user
            def currentUser = User.findByUsername(SecurityUtils.getSubject().getPrincipal())
            //get recprdtypeid
            def recordType = RecordType.get(salesOrderInstance.recordType.id)
            //set instance params
            salesOrderInstance.lastModifiedBy = currentUser
            salesOrderInstance.lastUpdated = new java.util.Date()
            salesOrderInstance.salesOrderDetails.each { 
                it.deliveryLimitation = it.deliveryLimitation?:new Date()
                it.specialDiscount = it.specialDiscount ?: 0
            }
            //save
            success = salesOrderInstance.validate() && salesOrderInstance.save(flush:true)
            if(!success){
                status.setRollbackOnly()
            }
        }
        return success
    }
    
    def validateDeliveryLimitation(orderDate, deliveryLimitation, product) {
        if(deliveryLimitation == null)
            return false
        def deliveryCycle = ProductCategory.withCriteria(uniqueResult:true){
            createAlias 'product', 'p'
            createAlias 'category', 'c'
            createAlias 'category.recordType', 'rt'
            projections {
                property('c.deliveryCycle')
            }
            join "product"
            join "category"
            join "category.recordType"
            eq("p.id", product)
            eq("rt.serialNumber", "2")
            eq("p.isActive", true)
        }
        
        return  deliveryLimitation >=  orderDate + deliveryCycle?:0
    }

    
    def validatePrice(productId, price){

        def result = 'N'

        def isAllowZeroPrice = ProductCategory.withCriteria{
            createAlias 'product', 'p'
            createAlias 'category', 'c'
            createAlias 'category.recordType', 'rt'
            projections {
                property('c.isAllowZeroPrice')
            }
            join "product"
            join "category"
            join "category.recordType"
            eq("p.id", productId)
            eq("rt.serialNumber", "5")
            eq("p.isActive", true)
        }

        if(isAllowZeroPrice.size() > 0){//有第五个属性，true为允许，false和null为不允许
            result = (isAllowZeroPrice[0] == true)?'Y':'N'
        }else{//没有第五个属性，默认为允许
            result = 'Y'
        }

        if(result == 'N' && price <= 0){
            return false
        }else{
            return true
        }
    }

    
    def validateSpecialDiscount(productId, specialDiscount){
        def result = true
        def isAllowSpecialDiscount = ProductCategory.withCriteria(uniqueResult:true){
            createAlias 'product', 'p'
            createAlias 'category', 'c'
            createAlias 'category.recordType', 'rt'
            projections {
                property('c.isAllowSpecialDiscount')
            }
            join "product"
            join "category"
            join "category.recordType"
            eq("p.id", productId)
            eq("rt.serialNumber", "5")
            eq("p.isActive", true)
        }
        if(isAllowSpecialDiscount != true && specialDiscount > 0){
            result = false
        }
        return result
    }    
    
	def isLocked(id){
        def result = 
		 WorkflowHistory.withCriteria(uniqueResult:true){
            createAlias 'step', 's'
            projections{
                property('s.lockRecord')
            }
            fetchMode "step", FM.JOIN
            eq("objectId", id.toLong())
            eq("objectName", 'salesOrder')
            order("id", "desc")
            maxResults(1)
		}
         return result
	}
    //判断ERP单号是否唯一
    
    def uniqueSerialNumber(String serialNumber){
        def result = true
        
        if(serialNumber != null){
            def count = SalesOrder.countBySerialNumber(serialNumber)

            if(count > 0){
                result = false
            }
        }

        return result
    }
    
}
